//
//  UIViewController+HHPage.m
//  Pods
//
//  Created by Basic on 2017/8/2.
//
//

#import "UIViewController+HHPage.h"
#import <BCFoundation/BCSwizzle.h>
#import <BCFoundation/BCFoundation.h>
//#import <BCFileLog/BCFileLog.h>
#import <BCComConfigKit/BCComConfigKit.h>
#import "UINavigationBar+BCHelper.h"
#import "UIBarButtonItem+BCHelper.h"
#import "UINavigationController+HHUIKit.h"

@interface UIViewController()

@end

@implementation UIViewController (HHPage)

#pragma mark - system
+(void)load  {}

- (void)bchh_viewDidLoad {
    if (!self.bc_enableSwizzle) {
        return;
    }
    self.bc_firstAppear = YES;
    self.hh_touchEndEditing = NO;
    self.extendedLayoutIncludesOpaqueBars = NO;
    self.edgesForExtendedLayout = UIRectEdgeNone;
    self.view.backgroundColor = BCComConfig.config.vcBgColor;
    BCLog(@"[bcui] %@ load",NSStringFromClass([self class]));
}
-(void)bchh_viewWillAppear:(BOOL)animated {
    if (!self.bc_enableSwizzle) {
        return;
    }
    if(![self isKindOfClass:[UINavigationController class]]) {
        
        //判断是否需要隐藏导航条
        if(self.navigationController.navigationBarHidden != self.hh_navigationBarHidden){
            [self.navigationController setNavigationBarHidden:self.hh_navigationBarHidden animated:animated];
        }
        //导航栏标题
        if (self.hh_navTitleColor) {
            NSMutableDictionary *titleAttributes = [[NSMutableDictionary alloc] init];
            titleAttributes[NSForegroundColorAttributeName] = self.hh_navTitleColor;
            titleAttributes[NSFontAttributeName] = BCComConfig.config.bcBoldFont(18);
            self.hh_titleAttributes = titleAttributes;
        }
        //导航栏背景 or 导航栏渐变色
        if (self.hh_navBgStartColor && self.hh_navBgEndColor) {//渐变背景
            [self.navigationController.navigationBar bc_showGradientLayer:self.hh_navBgStartColor withStartPoint:self.hh_navBgStartPoint withEndColor:self.hh_navBgEndColor withEndPoint:self.hh_navBgEndPoint];
        }
        else {//修改导航栏的颜色
            [self.navigationController.navigationBar bc_setBackgroundColor:self.hh_navBgColor];
        }
        //修改导航栏 分割线的颜色
        [self.navigationController.navigationBar bc_setSplitColor:self.hh_splitColor];
        //修改标题颜色
        if(self.hh_titleAttributes){
            [self.navigationController.navigationBar setTitleTextAttributes:self.hh_titleAttributes];
        }
        else {
            [self.navigationController bc_restoreTitle];
        }
        self.bc_isAppear = YES;
    }
    if (self.bc_firstAppear) {
        [self hh_addPageTapGesture];//添加  tap手势
    }
}
-(void)bchh_viewDidAppear:(BOOL)animated {
    if (!self.bc_enableSwizzle) {
        return;
    }
    if(![self isKindOfClass:[UINavigationController class]]){
        [self.navigationController.navigationBar bc_checkNavBarHasShow];
    }
    BCLog(@"[bcui] %@ app",NSStringFromClass([self class]));
}
-(void)bchh_viewWillDisappear:(BOOL)animated {
    if (!self.bc_enableSwizzle) {
        return;
    }
    //恢复appear 属性
    if(![self isKindOfClass:[UINavigationController class]]){
        self.bc_firstAppear = NO;
        self.bc_isAppear = NO;
    }
    //    //判断是否需要回复导航条
    //    if(self.hh_navigationBarHidden){
    //        [self.navigationController setNavigationBarHidden:!self.hh_navigationBarHidden animated:animated];
    //    }
    //    BCLog(@"%@ viewWillDisappear",NSStringFromClass([self class]));
}
-(void)bchh_viewDidDisappear:(BOOL)animated {
    if (!self.bc_enableSwizzle) {
        return ;
    }
    BCLog(@"[bcui] %@ disapp",NSStringFromClass([self class]));
}
-(void)bchh_dealloc
{
    if (!self.bc_enableSwizzle) {
        return;
    }
    BCLogDealloc();
}
-(UIStatusBarStyle )bchh_preferredStatusBarStyle
{
    return self.bc_statusBarStyle;
}



#pragma mark - 通用属性
-(BOOL)bc_enableSwizzle {
    id enableSwizzle = objc_getAssociatedObject(self, @selector(bc_enableSwizzle));
    if (enableSwizzle == nil) {
        //判断是否可以swizzle
        BOOL hh_canSwizle = YES;
        NSString *selfClass = NSStringFromClass([self class]);
        NSArray *classList = [selfClass componentsSeparatedByString:@"."];
        if (classList.count>1) {
            //兼容swift class: target.XXxxVC
            selfClass = classList.lastObject;
        }
        if([selfClass hasPrefix:@"UI"] || [selfClass hasPrefix:@"_UI"]  || [selfClass hasPrefix:@"_SFAppPassword"] || [selfClass hasPrefix:@"SFPassword"]  || [selfClass hasPrefix:@"CKSMS"] || [selfClass hasPrefix:@"CAM"] || [selfClass hasPrefix:@"PUUI"] || [selfClass hasPrefix:@"PUPhoto"] || [selfClass hasPrefix:@"PLPhoto"] || [selfClass hasPrefix:@"GS"] || [selfClass hasPrefix:@"Vod"] || [selfClass hasPrefix:@"AVPlayer"] || [selfClass hasPrefix:@"AVFullScreen"]){
            //CAM 开头：拍照库 ，PUUI：相册库，PLPhoto：相册编辑，CKSMS：短信page
            //GS,Vod 互动课堂SDK
            hh_canSwizle = NO;
        }
        else if([self isKindOfClass:[UITabBarController class]]) {
            hh_canSwizle = NO;
        }
        else if([self isKindOfClass:[UINavigationController class]]) {
            hh_canSwizle = NO;
        }
        self.bc_enableSwizzle = hh_canSwizle;
        return hh_canSwizle;
    }
    return [enableSwizzle boolValue];
}
-(void)setBc_enableSwizzle:(BOOL)bc_enableSwizzle {
    objc_setAssociatedObject(self, @selector(bc_enableSwizzle), @(bc_enableSwizzle), OBJC_ASSOCIATION_RETAIN_NONATOMIC);
}
- (BOOL)bc_firstAppear {
    return [objc_getAssociatedObject(self, @selector(bc_firstAppear)) boolValue];
}
- (void)setBc_firstAppear:(BOOL)bc_firstAppear {
    objc_setAssociatedObject(self, @selector(bc_firstAppear), @(bc_firstAppear), OBJC_ASSOCIATION_ASSIGN);
}

-(BOOL)bc_isAppear
{
    return [objc_getAssociatedObject(self, @selector(bc_isAppear)) boolValue];
    
}
-(void)setBc_isAppear:(BOOL)bc_isAppear
{
    objc_setAssociatedObject(self, @selector(bc_isAppear), @(bc_isAppear), OBJC_ASSOCIATION_ASSIGN);
}
-(BOOL)bc_disablePopGesture
{
    return [objc_getAssociatedObject(self, @selector(bc_disablePopGesture)) boolValue];
    
}
-(void)setBc_disablePopGesture:(BOOL)bc_disablePopGesture
{
    objc_setAssociatedObject(self, @selector(bc_disablePopGesture), @(bc_disablePopGesture), OBJC_ASSOCIATION_ASSIGN);
    self.navigationController.interactivePopGestureRecognizer.enabled = !bc_disablePopGesture;
}
-(BOOL)bc_disableRoute
{
    return [objc_getAssociatedObject(self, @selector(bc_disableRoute)) boolValue];
    
}
-(void)setBc_disableRoute:(BOOL)bc_disableRoute
{
    objc_setAssociatedObject(self, @selector(bc_disableRoute), @(bc_disableRoute), OBJC_ASSOCIATION_ASSIGN);
}

#pragma mark - 状态栏属性
-(UIStatusBarStyle)bc_statusBarStyle
{
    NSNumber *statusBarStyle = objc_getAssociatedObject(self, @selector(bc_statusBarStyle));
    return [statusBarStyle integerValue];
    
}
-(void)setBc_statusBarStyle:(UIStatusBarStyle)bc_statusBarStyle
{
    objc_setAssociatedObject(self, @selector(bc_statusBarStyle), @(bc_statusBarStyle), OBJC_ASSOCIATION_ASSIGN);
}

#pragma mark - 导航栏属性
-(BOOL)hh_navigationBarHidden
{
    return [objc_getAssociatedObject(self, @selector(hh_navigationBarHidden)) boolValue];
}
-(void)setHh_navigationBarHidden:(BOOL)hh_navigationBarHidden
{
    objc_setAssociatedObject(self, @selector(hh_navigationBarHidden), @(hh_navigationBarHidden), OBJC_ASSOCIATION_ASSIGN);
}
-(BOOL)hh_hideBackItem
{
    return [objc_getAssociatedObject(self, @selector(hh_hideBackItem)) boolValue];
}
-(void)setHh_hideBackItem:(BOOL)hh_hideBackItem
{
    self.navigationItem.hidesBackButton = hh_hideBackItem;
    if (hh_hideBackItem) {
        self.navigationItem.leftBarButtonItem = nil;
    }else{
        UIImage *itemImg = self.hh_navBackImage ?: BCComConfig.config.navBackImg;
        BCWeakObj(self);
        self.navigationItem.leftBarButtonItem = [[UIBarButtonItem alloc] bc_initWithButton:nil image:itemImg action:^(UIButton * _Nonnull sender) {
            BCStrongObj(self);
            [self.navigationController bc_backItemAction];
        }];
    }
    objc_setAssociatedObject(self, @selector(hh_hideBackItem), @(hh_hideBackItem), OBJC_ASSOCIATION_ASSIGN);
}
-(UIImage *)hh_navBackImage {
    return objc_getAssociatedObject(self, @selector(hh_navBackImage));
}
-(void)setHh_navBackImage:(UIImage *)hh_navBackImage {
    if (self.navigationItem.leftBarButtonItem) {
        [self.navigationItem.leftBarButtonItem bc_updateImage:hh_navBackImage highlightImage:nil disableImage:nil];
    }
    objc_setAssociatedObject(self, @selector(hh_navBackImage), hh_navBackImage, OBJC_ASSOCIATION_RETAIN_NONATOMIC);
}
-(UIColor *)hh_splitColor {
    UIColor *splitColor = objc_getAssociatedObject(self, @selector(hh_splitColor));
    if(!splitColor){
        splitColor = BCComConfig.config.navSplitColor;
    }
    return splitColor;
}
-(void)setHh_splitColor:(UIColor *)hh_splitColor {
    objc_setAssociatedObject(self, @selector(hh_splitColor), hh_splitColor, OBJC_ASSOCIATION_RETAIN_NONATOMIC);
}
-(UIColor *)hh_navBgColor {
    UIColor *navBgColor = objc_getAssociatedObject(self, @selector(hh_navBgColor));
    if(!navBgColor){
        navBgColor = BCComConfig.config.navBgColor;
    }
    return navBgColor;
}
-(void)setHh_navBgColor:(UIColor *)hh_navBgColor {
    objc_setAssociatedObject(self, @selector(hh_navBgColor), hh_navBgColor, OBJC_ASSOCIATION_RETAIN_NONATOMIC);
}
-(UIColor *)hh_navTitleColor {
    UIColor *navTitleColor = objc_getAssociatedObject(self, @selector(hh_navTitleColor));
    if(!navTitleColor){
        navTitleColor = BCComConfig.config.navTitleColor;
    }
    return navTitleColor;
}
-(void)setHh_navTitleColor:(UIColor *)hh_navTitleColor {
    objc_setAssociatedObject(self, @selector(hh_navTitleColor), hh_navTitleColor, OBJC_ASSOCIATION_RETAIN_NONATOMIC);
}
-(NSDictionary<id, id> *)hh_titleAttributes {
    return (NSDictionary<id, id> *)objc_getAssociatedObject(self, @selector(hh_titleAttributes));
}
-(void)setHh_titleAttributes:(NSDictionary<id, id> *)hh_titleAttributes
{
    objc_setAssociatedObject(self, @selector(hh_titleAttributes), hh_titleAttributes, OBJC_ASSOCIATION_RETAIN_NONATOMIC);
}
-(UIColor *)hh_navBgStartColor {
    return objc_getAssociatedObject(self, @selector(hh_navBgStartColor));
}
-(void)setHh_navBgStartColor:(UIColor *)hh_navBgStartColor {
    objc_setAssociatedObject(self, @selector(hh_navBgStartColor), hh_navBgStartColor, OBJC_ASSOCIATION_RETAIN_NONATOMIC);
}
- (CGPoint)hh_navBgStartPoint {
    NSValue *value = objc_getAssociatedObject(self, @selector(hh_navBgStartPoint));
    if(value) {
        CGPoint point;
        [value getValue:&point];
        return point;
    } else {
        return CGPointZero;
    }
}
- (void)setHh_navBgStartPoint:(CGPoint)hh_navBgStartPoint {
    NSValue *value = [NSValue value:&hh_navBgStartPoint withObjCType:@encode(CGPoint)];
    objc_setAssociatedObject(self, @selector(hh_navBgStartPoint), value,  OBJC_ASSOCIATION_RETAIN_NONATOMIC);
}
-(UIColor *)hh_navBgEndColor {
    return objc_getAssociatedObject(self, @selector(hh_navBgEndColor));
}
-(void)setHh_navBgEndColor:(UIColor *)hh_navBgEndColor {
    objc_setAssociatedObject(self, @selector(hh_navBgEndColor), hh_navBgEndColor, OBJC_ASSOCIATION_RETAIN_NONATOMIC);
}
- (CGPoint)hh_navBgEndPoint {
    NSValue *value = objc_getAssociatedObject(self, @selector(hh_navBgEndPoint));
    if(value) {
        CGPoint point;
        [value getValue:&point];
        return point;
    } else {
        return CGPointZero;
    }
}
- (void)setHh_navBgEndPoint:(CGPoint)hh_navBgEndPoint {
    NSValue *value = [NSValue value:&hh_navBgEndPoint withObjCType:@encode(CGPoint)];
    objc_setAssociatedObject(self, @selector(hh_navBgEndPoint), value,  OBJC_ASSOCIATION_RETAIN_NONATOMIC);
}

#pragma mark - 键盘相关
-(BOOL)hh_touchEndEditing
{
    return [objc_getAssociatedObject(self, @selector(hh_touchEndEditing)) boolValue];
}
-(void)setHh_touchEndEditing:(BOOL)hh_touchEndEditing
{
    objc_setAssociatedObject(self, @selector(hh_touchEndEditing), @(hh_touchEndEditing), OBJC_ASSOCIATION_ASSIGN);
}
static char kZHPageActionHandlerTapGestureKey;
- (void)hh_addPageTapGesture
{
    if (!self.hh_touchEndEditing) {//点击空白地方结束编辑
        return;
    }
    UITapGestureRecognizer *gesture = objc_getAssociatedObject(self, &kZHPageActionHandlerTapGestureKey);
    if (!gesture){
        gesture = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(hh_handlePageTapGesture:)];
        //不影响 touchesbegan 改变使用delegate方式
//        gesture.cancelsTouchesInView = NO;
        gesture.delegate = (id<UIGestureRecognizerDelegate>)self;
        [self.view addGestureRecognizer:gesture];
        objc_setAssociatedObject(self, &kZHPageActionHandlerTapGestureKey, gesture, OBJC_ASSOCIATION_RETAIN);
    }
}
///MARK: UIGestureRecognizerDelegate
- (BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer shouldReceiveTouch:(UITouch *)touch {
    // 默认UITableViewCell，UIButton不响应touch时间
    if ([touch.view isKindOfClass:[UITableViewCell class]] || [touch.view.superview isKindOfClass:[UITableViewCell class]]) {
        return NO;
    } else if ([touch.view isKindOfClass:[UICollectionViewCell class]] ||
               [touch.view.superview isKindOfClass:[UICollectionViewCell class]] || [touch.view.superview.superview isKindOfClass:[UICollectionView class]]) {
        return NO;
    } else if ([touch.view isKindOfClass:[UIButton class]]) {
        return NO;
    }
    // 判断指定的不响应views
    if (self.hh_rejectTouchViews.count > 0) {
        for (NSString *clsName in self.hh_rejectTouchViews) {
            if ([touch.view isKindOfClass:NSClassFromString(clsName)]) {
                return NO;
            }
        }
    }
    return YES;
}
- (void)hh_handlePageTapGesture:(UITapGestureRecognizer *)gesture {
    if (!self.bc_enableSwizzle) {
        return;
    }
    if(self.hh_touchEndEditing){
        BOOL autoEndEdit = YES;
        if (self.hh_touchEndEditBlock) {
            autoEndEdit = self.hh_touchEndEditBlock(gesture);
        }
        if (autoEndEdit) {
            [self.view endEditing:YES];
        }
    }
}
-(void)setHh_touchEndEditBlock:(BOOL (^)(UITapGestureRecognizer *))hh_touchEndEditBlock
{
    objc_setAssociatedObject(self, @selector(hh_touchEndEditBlock), hh_touchEndEditBlock, OBJC_ASSOCIATION_COPY);
}
-(BOOL (^)(UITapGestureRecognizer *))hh_touchEndEditBlock
{
    return objc_getAssociatedObject(self, @selector(hh_touchEndEditBlock));
}
-(NSArray *)hh_rejectTouchViews {
    return objc_getAssociatedObject(self, @selector(hh_rejectTouchViews));
}
-(void)setHh_rejectTouchViews:(NSArray *)hh_rejectTouchViews {
    objc_setAssociatedObject(self, @selector(hh_rejectTouchViews), hh_rejectTouchViews, OBJC_ASSOCIATION_RETAIN_NONATOMIC);
}
#pragma mark - 屏幕旋转
static BOOL kZHPageShouldAutorotate = YES;
+(void)setHh_shouldAutorotate:(BOOL)hh_shouldAutorotate {
    kZHPageShouldAutorotate = hh_shouldAutorotate;
}
+(BOOL)hh_shouldAutorotate {
    return kZHPageShouldAutorotate;
}
-(void)setHh_customAutorotate:(BOOL)hh_customAutorotate {
    objc_setAssociatedObject(self, @selector(hh_customAutorotate), @(hh_customAutorotate), OBJC_ASSOCIATION_ASSIGN);
}
-(BOOL)hh_customAutorotate {
    return [objc_getAssociatedObject(self, @selector(hh_customAutorotate)) boolValue];
}
static UIInterfaceOrientationMask kZHPageSupportedOrientations = UIInterfaceOrientationMaskPortrait;
+(void)setHh_supportedOrientations:(UIInterfaceOrientationMask)hh_supportedOrientations {
    kZHPageSupportedOrientations = hh_supportedOrientations;
}
+(UIInterfaceOrientationMask)hh_supportedOrientations {
    return kZHPageSupportedOrientations;
}
-(void)setHh_customOrientations:(BOOL)hh_customOrientations {
    objc_setAssociatedObject(self, @selector(hh_customOrientations), @(hh_customOrientations), OBJC_ASSOCIATION_ASSIGN);
}
-(BOOL)hh_customOrientations {
    return [objc_getAssociatedObject(self, @selector(hh_customOrientations)) boolValue];
}

//MARK: - 刘海适配相关
-(UIView *)bc_bottomSafeView {
    return (UIView *)objc_getAssociatedObject(self, @selector(bc_bottomSafeView));
}
-(void)setBc_bottomSafeView:(UIView *)bc_bottomSafeView {
    objc_setAssociatedObject(self, @selector(bc_bottomSafeView), bc_bottomSafeView, OBJC_ASSOCIATION_RETAIN_NONATOMIC);
}
- (void)bc_showBottomSafeView {
    UIView *bottomSafeView = [self bc_bottomSafeView];
    if (bottomSafeView == nil) {
        bottomSafeView = [[UIView alloc] initWithFrame:CGRectMake(0, self.view.frame.size.height-kBCScreenSafeAreaBottom, kBCSCREEN_WIDTH, kBCScreenSafeAreaBottom)];
        bottomSafeView.backgroundColor = [UIColor whiteColor];
        [self.view addSubview:bottomSafeView];
        [self setBc_bottomSafeView:bottomSafeView];
    }
}


#pragma mark - helper
- (void)bc_callPhone:(NSString*)phoneNum {
    NSString *callPhone = [NSString stringWithFormat:@"telprompt://%@", phoneNum];
    /// 防止iOS 10及其之后，拨打电话系统弹出框延迟出现
    dispatch_async(dispatch_get_global_queue(0, 0), ^{
        NSURL *phoneURL = [NSURL URLWithString:callPhone];
    #if __IPHONE_OS_VERSION_MIN_REQUIRED >= 100000
        NSDictionary<UIApplicationOpenExternalURLOptionsKey, id> *options = [[NSDictionary<UIApplicationOpenExternalURLOptionsKey, id> alloc] init];
        [[UIApplication sharedApplication] openURL:phoneURL options:options completionHandler:nil];
    #else
        [[UIApplication sharedApplication] openURL:phoneURL];
    #endif
    });
}
+ (UIViewController *)bc_topPage
{
    UIViewController *vcRoot = [[[UIApplication sharedApplication] delegate] window].rootViewController;
    return [[self class] bc_topViewController:vcRoot];
}
+ (UIViewController *)bc_topViewController:(UIViewController *)viewController
{
    if ([viewController isKindOfClass:[UINavigationController class]]) {
        return [[self class] bc_topViewController:[(UINavigationController *)viewController topViewController]];
    }
    else if ([viewController isKindOfClass:[UITabBarController class]]) {
        return [[self class] bc_topViewController:[(UITabBarController *)viewController selectedViewController]];
    }
    else if (viewController.presentedViewController && !viewController.presentedViewController.bc_disableRoute) {
        return [[self class] bc_topViewController:viewController.presentedViewController];
    }
    return  viewController;
}

+ (UIViewController *)bc_findPage:(Class )pageCls
{
    UIViewController *vcRoot = [[[UIApplication sharedApplication] delegate] window].rootViewController;
    return [[self class] bc_findPageHandle:vcRoot pageCls:pageCls];
}

+ (UIViewController *)bc_findPageHandle:(UIViewController *)viewController pageCls:(Class )pageCls
{
    if ([viewController isKindOfClass:[UINavigationController class]]) {
        UINavigationController *navcTmp = (UINavigationController *)viewController;
        UIViewController *findPage = nil;
        for (NSInteger i=navcTmp.viewControllers.count-1; i>=0; i--) {//倒序开始查找
            UIViewController *pageTmp = navcTmp.viewControllers[i];
            if ([pageTmp isKindOfClass:pageCls]) {
                findPage = pageTmp;
                break;
            }
        }
        if (!findPage && navcTmp.presentedViewController) {
            findPage = [self bc_findPageHandle:navcTmp.presentedViewController pageCls:pageCls];
        }
        return findPage;
    }
    else if ([viewController isKindOfClass:[UITabBarController class]]) {
        UITabBarController *tabbarTmp = (UITabBarController *)viewController;
        UIViewController *findPage = nil;
        for (NSInteger i=tabbarTmp.viewControllers.count-1; i>=0; i--) {//倒序开始查找
            UIViewController *pageTmp = tabbarTmp.viewControllers[i];
            findPage = [self bc_findPageHandle:pageTmp pageCls:pageCls];
            if (findPage) {
                break;
            }
        }
        if (findPage) {
            return findPage;
        }
    }
    return  nil;
}

+ (UINavigationController *)bc_navPage
{
    UIViewController *vcRoot = [[[UIApplication sharedApplication] delegate] window].rootViewController;
    return [[self class] bc_findNavigationController:vcRoot];
}
+ (UINavigationController *)bc_findNavigationController:(UIViewController *)viewController
{
    if ([viewController isKindOfClass:[UINavigationController class]]) {
        return (UINavigationController *)viewController;
    }
    else if ([viewController isKindOfClass:[UITabBarController class]]) {
        return [[self class] bc_findNavigationController:[(UITabBarController *)viewController selectedViewController]];
    }
    else if (viewController.presentedViewController && !viewController.presentedViewController.bc_disableRoute) {
        return [[self class] bc_findNavigationController:viewController.presentedViewController];
    }
    return  viewController.navigationController;
}
@end
